/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.evangelion.core.controller;

import com.evangelion.core.bean.*;
import com.evangelion.core.daoImpl.ConnectionUtil;
import com.evangelion.core.utils.*;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;
import org.primefaces.context.RequestContext;
import org.primefaces.model.DefaultStreamedContent;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.util.*;

/**
 * @author Kellycasma
 */
@ManagedBean
@ViewScoped
public class FacturaController extends MensajesFace implements Serializable {

    private Factura factura;

    private String valorBusqueda;
    private Date fechaI;
    private Date fechaF;
    private List<Factura> listaFactura;
    private List<Vehiculo> listaVehiculo;
    private List<Grupo> listaGrupo;
    private List<Seccione> listaSeccion;
    private List<Proveedor> listaProveedor;

    private Movimiento movimiento;
    private DefaultStreamedContent dc;
    private DefaultStreamedContent dcDescarga;
    private String idFacturaAlumno;
    private Date fechaFactura;

    @PostConstruct
    public void init() {
        super.init();

        factura = new Factura();
        factura.setCliente(new Cliente());
        factura.setSeccion(new Seccione());
        listaFactura = new ArrayList<Factura>();

        System.out.println("Lista............ " + listaFactura.size());
        listaVehiculo = VehiculoConverter.linkTypesDB;
        listaGrupo = GrupoConverter.linkTypesDB;
        listaSeccion = SeccionConverter.linkTypesDB;
        listaProveedor = ProveedorConverter.linkTypesDB;

        listaFactura = fsi.searchByMatricula(seccion, "", new Date(), new Date());
    }

    private void printPDFfacturaDescarga(Map parameters, String archivo, String id) {
        try {
            Connection conexion = connectionUtil.getConnection();
            String urlMaster = ConnectionUtil.getServletContext().getRealPath(REPORT_FOLDER + archivo);
            JasperReport reporteMaster = null;
            try {
                reporteMaster = (JasperReport) JRLoader.loadObject(urlMaster);
            } catch (Exception e) {
                e.printStackTrace();
            }
            JasperPrint print = null;
            print = JasperFillManager.fillReport(reporteMaster, parameters, conexion);
            byte[] bytes = JasperExportManager.exportReportToPdf(print);
            System.out.println("byte: " + bytes.length);
            if (bytes.length >= 1211 && bytes.length <= 1400) {
                System.out.println("tamano menor");
                setDcDescarga(null);
                System.out.println("El reporte no genero ningun resultado");
            } else {
                InputStream stream = new ByteArrayInputStream(bytes);
                setDcDescarga(new DefaultStreamedContent(stream, "application/pdf", "/general/factura_" + id + ".pdf"));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void printPDFfactura(Map parameters, String archivo, String id) {
        try {
            Connection conexion = connectionUtil.getConnection();
            String urlMaster = ConnectionUtil.getServletContext().getRealPath(REPORT_FOLDER + archivo);
            JasperReport reporteMaster = null;
            try {
                reporteMaster = (JasperReport) JRLoader.loadObject(urlMaster);
            } catch (Exception e) {
                e.printStackTrace();
            }
            JasperPrint print = null;
            print = JasperFillManager.fillReport(reporteMaster, parameters, conexion);
            byte[] bytes = JasperExportManager.exportReportToPdf(print);
            System.out.println("byte: " + bytes.length);
            if (bytes.length >= 1211 && bytes.length <= 1400) {
                System.out.println("tamano menor");
                setDc(null);
                System.out.println("El reporte no genero ningun resultado");
            } else {
                InputStream stream = new ByteArrayInputStream(bytes);
                setDc(new DefaultStreamedContent(stream, "application/pdf", "/general/factura_" + id + ".pdf"));
                System.out.println("Reporte generado exitosamente : " + getDc().getStream().toString());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void descargarFactura(String matricula, Date fecha) {
        String archivo = "reporteMantenimientoVehiculo.jasper";
        Map parameters = new HashMap();
        parameters.put("matricula", matricula);
        parameters.put("fechaI", fecha);
        parameters.put("fechaF", fecha);
        matricula = "" + matricula;
        printPDFfacturaDescarga(parameters, archivo, matricula.trim());
    }

    public void imprimirFactura(ActionEvent e) {
        String archivo = "reporteMantenimientoVehiculo.jasper";
        Map parameters = new HashMap();
        parameters.put("matricula", getIdFacturaAlumno());
        parameters.put("fechaI", getFechaFactura());
        parameters.put("fechaF", getFechaFactura());
        String matricula = "" + getIdFacturaAlumno();
        printPDFfactura(parameters, archivo, matricula);
    }

    public void save() {
        //En la tabla 'facturas' cambie el campo iva de int a double
        RequestContext context = RequestContext.getCurrentInstance();
        try {
            factura.setCliente(usuario.getCliente());
            factura.setSeccion(seccion);
            factura.setIva(21);
            fsi.save(factura);

            setIdFacturaAlumno(getFactura().getVehiculo().getMatricula());

            movimiento = new Movimiento();

            movimiento.setFecha(new Date());
            movimiento.setConcepto(factura.getConcepto());

            movimiento.setIva(factura.getIva());

            movimiento.setDebe(Double.valueOf(factura.getTotal()));
            movimiento.setImpIVA(movimiento.getDebe() * movimiento.getIva() / 100);
            movimiento.setTotal(movimiento.getDebe() + movimiento.getImpIVA());
            movimiento.setCliente(factura.getCliente());
            movimiento.setSeccion(factura.getSeccion());
            movimiento.setBc(0.0);

            movimientoService.save(movimiento);

            setFechaFactura(getFactura().getFecha());

            limpiarForm();
            msgCambiosGuardados();
            init();
            context.addCallbackParam("statusTransaction", true);
            context.addCallbackParam("idFacturaAlumno", getIdFacturaAlumno());
        } catch (Exception e) {
            context.addCallbackParam("statusTransaction", false);
            context.addCallbackParam("errorTransaction", "ERROR : " + e);
        }
    }

    public void limpiarForm() {
        factura = new Factura();
    }

    public void search() {
        listaFactura = fsi.searchByMatricula(seccion, valorBusqueda, fechaI, fechaF);
    }

    public Factura getFactura() {
        return factura;
    }

    public void setFactura(Factura factura) {
        this.factura = factura;
    }

    public List<Vehiculo> getListaVehiculo() {
        return listaVehiculo;
    }

    public void setListaVehiculo(List<Vehiculo> listaVehiculo) {
        this.listaVehiculo = listaVehiculo;
    }

    public List<Grupo> getListaGrupo() {
        return listaGrupo;
    }

    public void setListaGrupo(List<Grupo> listaGrupo) {
        this.listaGrupo = listaGrupo;
    }

    public List<Proveedor> getListaProveedor() {
        return listaProveedor;
    }

    public void setListaProveedor(List<Proveedor> listaProveedor) {
        this.listaProveedor = listaProveedor;
    }

    public String getValorBusqueda() {
        return valorBusqueda;
    }

    public void setValorBusqueda(String valorBusqueda) {
        this.valorBusqueda = valorBusqueda;
    }

    public Date getFechaI() {
        return fechaI;
    }

    public void setFechaI(Date fechaI) {
        this.fechaI = fechaI;
    }

    public Date getFechaF() {
        return fechaF;
    }

    public void setFechaF(Date fechaF) {
        this.fechaF = fechaF;
    }

    public List<Factura> getListaFactura() {
        return listaFactura;
    }

    public void setListaFactura(List<Factura> listaFactura) {
        this.listaFactura = listaFactura;
    }

    public List<Seccione> getListaSeccion() {
        return listaSeccion;
    }

    public void setListaSeccion(List<Seccione> listaSeccion) {
        this.listaSeccion = listaSeccion;
    }

    /**
     * @return the movimiento
     */
    public Movimiento getMovimiento() {
        return movimiento;
    }

    /**
     * @param movimiento the movimiento to set
     */
    public void setMovimiento(Movimiento movimiento) {
        this.movimiento = movimiento;
    }

    /**
     * @return the idFacturaAlumno
     */
    public String getIdFacturaAlumno() {
        return idFacturaAlumno;
    }

    /**
     * @param idFacturaAlumno the idFacturaAlumno to set
     */
    public void setIdFacturaAlumno(String idFacturaAlumno) {
        this.idFacturaAlumno = idFacturaAlumno;
    }

    /**
     * @return the dc
     */
    public DefaultStreamedContent getDc() {
        return dc;
    }

    /**
     * @param dc the dc to set
     */
    public void setDc(DefaultStreamedContent dc) {
        this.dc = dc;
    }

    /**
     * @return the fechaFactura
     */
    public Date getFechaFactura() {
        return fechaFactura;
    }

    /**
     * @param fechaFactura the fechaFactura to set
     */
    public void setFechaFactura(Date fechaFactura) {
        this.fechaFactura = fechaFactura;
    }

    /**
     * @return the dcDescarga
     */
    public DefaultStreamedContent getDcDescarga() {
        return dcDescarga;
    }

    /**
     * @param dcDescarga the dcDescarga to set
     */
    public void setDcDescarga(DefaultStreamedContent dcDescarga) {
        this.dcDescarga = dcDescarga;
    }
}
